home *** CD-ROM | disk | FTP | other *** search
- /*
- * Cross Development System for Atari ST
- * Copyright (c) 1988, Memorial University of Newfoundland
- *
- * See ChangeLog for further history ++jrb
- *
- * 1.5 ERS modified for benefit of 16 bit compilers
- * 1.4 ERS
- * Changed BIOS calls into GEMDOS calls.
- *
- * 1.3 jrd
- *
- * Revision 1.2 88/02/03 22:56:30 m68k
- * Added unix like tty driver stuff
- *
- * Revision 1.1 88/01/29 17:31:39 m68k
- * Initial revision
- *
- */
- #include <osbind.h>
- #include <ioctl.h>
- #include <signal.h>
- #include <tchars.h>
- #include <unistd.h>
- #include <device.h>
- #include <limits.h>
- #include <errno.h>
- #include "lib.h"
- #ifndef _COMPILER_H
- #include <compiler.h>
- #endif
-
- #define iswhite(c) ((c) == ' ' || (c) == '\t')
- #define isvisable(c) ((unsigned char)(c) >= ' ')
- #define echochar(fd, c) ((void)((__ttymode & ECHO) && _echochar((fd), (c))))
- #define delchar(fd, n) ((void)((__ttymode & ECHO) ? \
- _delchar((fd), (n)),0 : 0 ))
-
- extern int errno;
- extern int __col_pos; /* defined in write.c */
- static int start_col;
- static char *thebuf;
-
- static int _echochar __PROTO((int fd, int c));
- static void _delchar __PROTO((int fd, int n));
- static int str_length __PROTO((char *p, int n));
-
- extern unsigned int console_read_byte(int);
- extern void console_write_byte(int, int);
- extern int console_input_status(int);
-
- #ifdef __MSHORT__
- int
- read(fd, buf, nbytes)
- int fd;
- void *buf;
- unsigned int nbytes;
- {
- return (int)(_read(fd, buf, (unsigned long) nbytes));
- }
-
- #else
-
- asm(".stabs \"_read\",5,0,0,__read"); /* dept of clean tricks */
-
- #endif
-
- long
- _read(fd, buf, n)
- int fd;
- void *buf;
- unsigned long n;
- {
- long rval, nbytes;
- long cnt = 0;
- char *p = buf;
- struct _device *dev;
-
- if(n > ((unsigned long)LONG_MAX))
- {
- errno = EBADARG;
- return -1L;
- }
-
- nbytes = (long)n;
- if ((dev = _dev_fd(fd)) && dev->read)
- return (*dev->read)(fd, buf, nbytes);
-
- if (!isatty(fd))
- { /* really cant do much about the signdness of nbytes here */
- if ((rval = Fread(fd, nbytes, buf)) < 0)
- {
- errno = -rval;
- rval = -1;
- }
- return rval;
- }
- thebuf = buf;
- start_col = __col_pos;
- while (1) {
- *p = console_read_byte(fd);
- if (__ttymode & RAW)
- {
- if (__ttymode & ECHO)
- {
- console_write_byte(fd, *p);
- if (*p == '\r')
- __col_pos = 0;
- else if (isvisable(*p))
- __col_pos++;
- }
- if (++cnt >= nbytes || !console_input_status(fd))
- return cnt;
- p++;
- continue;
- }
- if ((__ttymode & CRMOD) && *p == '\r')
- *p = '\n';
- if (*p == __tchars[TC_INTRC])
- {
- /* Do the bsd thing here, i.e. flush buffers
- * and continue to read after the interupt
- */
- echochar(fd, *p);
- p = buf;
- cnt = 0;
- raise(SIGINT);
- }
- else
- if (*p == __tchars[TC_QUITC])
- {
- echochar(fd, *p);
- p = buf;
- cnt = 0;
- raise(SIGQUIT);
- }
- if (__ttymode & CBREAK)
- {
- if (*p == __tchars[TC_LNEXTC])
- *p = console_read_byte(fd);
- if (__ttymode & ECHO)
- {
- if (*p == '\n' && (__ttymode & CRMOD))
- {
- console_write_byte(fd, '\n');
- console_write_byte(fd, '\r');
- __col_pos = 0;
- }
- else
- (void) _echochar(fd, *p);
- }
- ++cnt;
-
- if (!console_input_status(fd))
- return cnt;
- p++;
- }
- else
- if (*p == __tchars[TC_LNEXTC])
- {
- if (__ttymode & ECHO)
- {
- console_write_byte(fd, '^');
- console_write_byte(fd, '\b');
- }
- *p = console_read_byte(fd);
- echochar(fd, *p++);
- cnt++;
- }
- else
- if (*p == __tchars[TC_EOFC])
- {
- if (__ttymode & ECHO)
- {
- int i = _echochar(fd, *p);
- __col_pos -= i;
- while (i-- > 0)
- console_write_byte(fd, '\b');
- }
- return cnt;
- }
- else
- if (*p == '\n' || *p == __tchars[TC_BRKC])
- {
- if (__ttymode & ECHO)
- if (*p == '\n')
- {
- console_write_byte(fd, '\n');
- if (__ttymode & CRMOD)
- {
- console_write_byte(fd, '\r');
- __col_pos = 0;
- }
- }
- else
- (void) _echochar(fd, *p);
- return ++cnt;
- }
- else
- if ((*p == __tchars[TC_ERASE]) || (*p == __tchars[TC_ERASE]))
- {
- if (cnt)
- {
- --p; --cnt;
- delchar(fd, (int)cnt);
- }
- }
- else
- if (*p == __tchars[TC_KILL])
- {
- while (--cnt >= 0)
- {
- delchar(fd, (int)cnt);
- p--;
- }
- cnt = 0;
- }
- else
- if (*p == __tchars[TC_WERASC])
- {
- p--;
- while (cnt && iswhite(*p))
- {
- --p; --cnt;
- delchar(fd, (int)cnt);
- }
- while (cnt && !iswhite(*p))
- {
- --p; --cnt;
- delchar(fd, (int)cnt);
- }
- p++;
- }
- else
- if (*p == __tchars[TC_RPRNTC])
- {
- char *s;
-
- echochar(fd, __tchars[TC_RPRNTC]);
- console_write_byte(fd, '\r');
- console_write_byte(fd, '\n');
- __col_pos = 0;
- start_col = 0;
- if (__ttymode & ECHO)
- for (s = buf ; s < p ; s++)
- echochar(fd, *s);
- }
- else
- {
- echochar(fd, *p); p++;
- cnt++;
- }
- if (cnt >= nbytes)
- return cnt;
- }
- /*NOTREACHED*/
- }
-
- static int
- _echochar(fd, c)
- int fd;
- int c;
- {
- int len = 0;
-
- c &= 0xff;
- if (c < ' ') {
- if (c == '\t') {
- int i;
-
- len = ((__col_pos | 7) + 1) - __col_pos;
- if (__ttymode & XTABS)
- for (i = len ; i-- ;)
- console_write_byte(fd, ' ');
- else
- console_write_byte(fd, '\t');
- } else {
- console_write_byte(fd, '^');
- console_write_byte(fd, c + 0x40);
- len += 2;
- }
- } else if (c == 0x7f) {
- console_write_byte(fd, '^');
- console_write_byte(fd, '?');
- len += 2;
- } else {
- console_write_byte(fd, c);
- len++;
- }
- __col_pos += len;
- return len;
- }
-
- static void
- _delchar(fd, n)
- int fd, n;
- {
- int len = 0;
- char c = thebuf[n];
-
- if ((c >= 0 && c < ' ') || c == 0x7f) {
- if (c == '\t')
- len = __col_pos - str_length(thebuf, n);
- else
- len += 2;
- } else
- len++;
- __col_pos -= len;
- while (len--) {
- console_write_byte(fd, '\b');
- console_write_byte(fd, ' ');
- console_write_byte(fd, '\b');
- }
- }
-
- static int
- str_length(p, n)
- char *p;
- int n;
- {
- int pos = start_col;
- char c;
-
- while (n--) {
- c = *p++;
- if ((c >= 0 && c < ' ') || c == 0x7f)
- if (c == '\t')
- pos = (pos | 7) + 1;
- else
- pos += 2;
- else
- pos++;
- }
- return pos;
- }
-